/*
 * Copyright (c) 2024. hallele, Inc All rights reserved.
 */

package cn.hallele.ms.starter.web.interceptor;

import cn.hallele.infrastructure.metadata.constant.HttpConst;
import cn.hallele.infrastructure.util.NetUtil;
import cn.hallele.infrastructure.util.ObjectUtil;
import cn.hallele.infrastructure.util.SpringUtil;
import cn.hallele.infrastructure.util.bean.LoginUser;
import cn.hallele.ms.starter.web.config.proereties.FeignProperties;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Enumeration;
import java.util.List;
import java.util.Objects;

/**
 * hallele_mc_core
 *
 * @author anle5
 * @since 2024/11/16 21:46
 */
@Slf4j
public class FeignRequestInterceptor implements RequestInterceptor {
    private static final FeignProperties PROPERTIES = SpringUtil.getBean(FeignProperties.class);

    /**
     * Called for every request. Add data using methods on the supplied {@link RequestTemplate}.
     *
     * @param template template
     */
    @Override
    public void apply(RequestTemplate template) {
        List<String> whiteHeaders = PROPERTIES.getWhiteHeaders();
        LoginUser loginUser = NetUtil.getLoginUser();
        if (ObjectUtil.containsIgnoreCase(whiteHeaders, HttpConst.INITIATOR_ID)
                && !template.headers().containsKey(HttpConst.INITIATOR_ID)
                && ObjectUtil.isNotNull(loginUser)) {
            template.header(HttpConst.INITIATOR_ID, String.valueOf(loginUser.getId()));
        }

        final ServletRequestAttributes attributes = NetUtil.getServletRequestAttributes();
        if (Objects.isNull(attributes)) {
            // 兼容hystrix限流后，获取不到ServletRequestAttributes的问题（使拦截器直接失效）
            log.error("[attributes] is null. FeignRequestInterceptor is invalid!");
            return;
        }

        HttpServletRequest request = attributes.getRequest();
        Enumeration<String> headerNames = request.getHeaderNames();
        if (Objects.nonNull(headerNames)) {

            while (headerNames.hasMoreElements()) {
                String name = headerNames.nextElement();
                if (ObjectUtil.containsIgnoreCase(whiteHeaders, name)) {
                    String value = request.getHeader(name);
                    template.header(name, value);
                }
            }
        }
    }
}
